1 module hip.event.handlers.mouse;
2 public import hip.api.input.mouse;
3 import hip.math.vector;
4 import hip.event.handlers.button;
5 import hip.error.handler;
6 import hip.util.data_structures;
7 import hip.util.reflection;
8 
9 private enum HipMouseButtonCount = HipMouseButton.button2;
10 static assert(HipMouseButton.invalid - HipMouseButtonCount ==  2); //any + invalid
11 
12 class HipMouse
13 {
14     Vector2[] positions;
15     Vector2[] lastPositions;
16     Vector3 scroll;
17     HipButtonMetadata[HipMouseButtonCount] metadatas;
18 
19     this()
20     {
21         positions = new Vector2[](1); //Start it with at least 1
22         lastPositions = new Vector2[](1); //Start it with at least 1
23         positions[0] = Vector2(0,0);
24         lastPositions[0] = Vector2(0,0);
25         foreach(i; 0..HipMouseButtonCount)
26             metadatas[i] = new HipButtonMetadata(cast(int)i);
27     }
28 
29     void setPressed(HipMouseButton btn, bool pressed)
30     {
31         metadatas[cast(int)btn].setPressed(pressed);
32     }
33 
34     bool isPressed(HipMouseButton btn = HipMouseButton.any)
35     {
36         if(btn == HipMouseButton.any)
37         {
38             foreach(b; 0..metadatas.length)
39             {
40                 if(metadatas[b].isPressed)
41                     return true;
42             }
43             return false;
44         }
45         return metadatas[btn].isPressed;
46     }
47 
48     bool isJustPressed(HipMouseButton btn)
49     {
50         if(btn == HipMouseButton.any)
51         {
52             foreach(b; 0..metadatas.length)
53             {
54                 if(metadatas[b].isJustPressed)
55                     return true;
56             }
57             return false;
58         }
59         return metadatas[btn].isJustPressed;
60     }
61     bool isJustReleased(HipMouseButton btn)
62     {
63         if(btn == HipMouseButton.any)
64         {
65             foreach(b; 0..metadatas.length)
66             {
67                 if(metadatas[b].isJustReleased)
68                     return true;
69             }
70             return false;
71         }
72         return metadatas[btn].isJustReleased;
73     }
74     void setPosition(float x, float y, uint id = 0)
75     {
76         if(id+1 > positions.length)
77             positions.length = id+1;
78         if(id+1 > lastPositions.length)
79         {
80             lastPositions.length = id+1;
81         }
82         lastPositions[id] = positions[id];
83         ErrorHandler.assertExit(id < positions.length, "Touch ID out of range");
84         positions[id].x=x;
85         positions[id].y=y;
86     }
87 
88     HipButtonMetadata getMetadata(HipMouseButton btn = HipMouseButton.any)
89     {
90         if(btn == HipMouseButton.any)
91             btn = HipMouseButton.left;
92         return metadatas[btn];
93     }
94     void setScroll(float x, float y, float z)
95     {
96         scroll.x=x;
97         scroll.y=y;
98         scroll.z=z;
99     }
100     
101 
102     ///Use the ID for getting the touch, may return null
103     Vector2 getPosition(uint id = 0)
104     {
105         if(id > positions.length) return Vector2.zero;
106         return positions[id];
107     }
108     Vector2 getDeltaPosition(uint id = 0)
109     {
110         if(id > positions.length) return Vector2.zero;
111 
112         return positions[id] - lastPositions[id];
113     }
114     Vector3 getScroll(){return scroll;}
115     ubyte getMulticlickCount(HipMouseButton btn = HipMouseButton.left)
116     {
117         import hip.error.handler;
118         if(btn == HipMouseButton.any)
119             ErrorHandler.showWarningMessage("getMulticlickCount", "Can't get multiclick count for any button.");
120         return metadatas[btn].clickCount;
121     }
122 
123     bool isDoubleClicked(HipMouseButton btn = HipMouseButton.left)
124     {
125         if(btn == HipMouseButton.any)
126         {
127             foreach(b; 0..metadatas.length)
128             {
129                 if(metadatas[b].clickCount == 2 && metadatas[b]._isNewState)
130                     return true;
131             }
132             return false;
133         }
134         return metadatas[btn].clickCount == 2 && metadatas[btn]._isNewState;
135     }
136 
137     void postUpdate()
138     {
139         for(int i = 0; i < metadatas.length; i++)
140             metadatas[i]._isNewState = false;
141         for(int i = 0; i < lastPositions.length; i++)
142             lastPositions[i] = positions[i];
143         setScroll(0,0,0);
144     }
145 }